package Chatting;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.StringTokenizer;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

/**
 * 로그인 창 만들기
 * 
 * @author Hong
 */
public class Login extends JFrame implements ActionListener, Runnable {

	JPanel global = new JPanel();
	GridLayout gridLayout1 = new GridLayout();
	JPanel jPanel1 = new JPanel();
	JPanel jPanel2 = new JPanel();
	JPanel jPanel3 = new JPanel();
	JLabel ip = new JLabel();
	JLabel name = new JLabel();
	JTextField ipTF = new JTextField("192.168.10.102");
	JTextField nameTF = new JTextField("MK");
	JButton cancel = new JButton();
	JButton ok = new JButton();
	Font f = new Font("SansSerif", 0, 12);

	String myid;
	BufferedReader in;
	BufferedWriter out;
	Socket s;
	Chat chat = new Chat();
	ReName re = new ReName();
	Paper paper = new Paper();

	public Login() {
		super("Login!");
		try {
			jbInit();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void jbInit() throws Exception {
		this.getContentPane().setBackground(new Color(249, 255, 255));
		this.getContentPane().setLayout(null);
		global.setBorder(BorderFactory.createEtchedBorder());
		global.setOpaque(false);
		global.setBounds(new Rectangle(3, 3, 246, 114));
		global.setLayout(gridLayout1);
		gridLayout1.setRows(3);
		gridLayout1.setColumns(1);
		gridLayout1.setVgap(5);
		jPanel3.setBorder(BorderFactory.createEtchedBorder());
		jPanel3.setOpaque(false);
		jPanel3.setLayout(null);
		jPanel2.setOpaque(false);
		jPanel2.setLayout(null);
		jPanel1.setOpaque(false);
		jPanel1.setLayout(null);
		ip.setFont(new java.awt.Font("SansSerif", 0, 12));
		ip.setText("   I        P   : ");
		ip.setBounds(new Rectangle(6, 3, 66, 27));
		name.setBounds(new Rectangle(6, 0, 66, 27));
		name.setFont(new java.awt.Font("SansSerif", 0, 12));
		name.setText("  대화명  : ");
		ipTF.setBounds(new Rectangle(78, 3, 163, 27));
		nameTF.setBounds(new Rectangle(78, 0, 163, 27));
		cancel.setFont(new java.awt.Font("SansSerif", 0, 12));
		cancel.setBorder(BorderFactory.createRaisedBevelBorder());
		cancel.setText("취 소");
		cancel.setBounds(new Rectangle(126, 2, 67, 26));
		ok.setBounds(new Rectangle(48, 2, 67, 26));
		ok.setFont(new java.awt.Font("SansSerif", 0, 12));
		ok.setBorder(BorderFactory.createRaisedBevelBorder());
		ok.setText("확 인");
		this.getContentPane().add(global, null);
		global.add(jPanel1, null);
		jPanel1.add(ip, null);
		jPanel1.add(ipTF, null);
		global.add(jPanel2, null);
		jPanel2.add(name, null);
		jPanel2.add(nameTF, null);
		global.add(jPanel3, null);
		jPanel3.add(cancel, null);
		jPanel3.add(ok, null);

		setBounds(200, 200, 259, 155);
		setVisible(true);

		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});

		chat.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				closeProcess();
				System.exit(0);
			}
		});

		// 이벤트 추가 작업
		nameTF.addActionListener(this);
		ok.addActionListener(this);
		cancel.addActionListener(this);
		chat.globalsend.addActionListener(this);

		chat.rename.addActionListener(this);
		re.ok.addActionListener(this);
		re.newname.addActionListener(this);
		re.cancel.addActionListener(this);

		chat.close.addActionListener(this);

		chat.whomsend.addActionListener(this);

		chat.paper.addActionListener(this);
		paper.ok.addActionListener(this);
		paper.cancel.addActionListener(this);
		paper.answer.addActionListener(this);

	}

	/**
	 * 로그인 메인 메서드
	 */
	public static void main(String[] args) {
		new Login();
	}

	public void actionPerformed(ActionEvent e) {
		Object ob = e.getSource();
		// 접속 처리(로그인)
		if (ob == nameTF || ob == ok) {
			connectProcess();
		} else if (ob == cancel) {
			setVisible(false);
		} else if (ob == chat.globalsend) {
			sendProcess();
		} else if (ob == chat.rename) {
			re.oldname.setText(myid);
			re.setVisible(true);
		} else if (ob == re.ok || ob == re.newname) {
			renameProcess();
		} else if (ob == re.cancel) {
			re.setVisible(false);
		} else if (ob == chat.close) {
			closeProcess();
			System.exit(0);
		} else if (ob == chat.whomsend) {
			whomProcess();
		} else if (ob == chat.paper) { // 쪽지보내기
			if (chat.idx == -1) {
				JOptionPane.showMessageDialog(this, "쪽지보낼 상대방을 선택하세요~");
				return;
			}
			if (myid.equals(chat.item)) {
				JOptionPane.showMessageDialog(this, "자기 자신한테는 쪽지보내면 안되요~");
				return;
			}
			paper.to.setText(chat.item);
			paper.from.setText(myid);
			paper.letter.requestFocus();
			paper.setVisible(true);
			paper.card.show(paper.south1, "ok");
		} else if (ob == paper.ok) {
			paperProcess();
		} else if (ob == paper.answer) {
			String to = paper.to.getText();
			String from = paper.from.getText();
			paper.to.setText(from);
			paper.from.setText(to);
			paper.letter.append("\n-------------------------\n");
			paperProcess();
			paper.setVisible(false);
			// paper.card.show(paper.south1,"ok");
		} else if (ob == paper.cancel) {
			paper.from.setText("");
			paper.to.setText("");
			paper.letter.setText("");
			paper.setVisible(false);
		}
	}

	public void connectProcess() {
		String ip = ipTF.getText().trim();
		if (ip.length() < 1) {
			JOptionPane.showMessageDialog(this, "접속할 서버의 ip 를 입력해주세요");
			ipTF.requestFocus();
			return;
		}
		myid = nameTF.getText();
		if (myid.length() < 1) {
			JOptionPane.showMessageDialog(this, "닉네임을 입력해주세요");
			nameTF.requestFocus();
			return;
		}

		try {
			s = new Socket(ip, 5000);
			chat.area.append("접속 성공!!\n");
			setVisible(false);
			chat.globalsend.requestFocus();
			chat.setTitle("[" + myid + "님의 채팅창]");
			chat.setVisible(true);
			in = new BufferedReader(new InputStreamReader(s.getInputStream()));
			out = new BufferedWriter(
					new OutputStreamWriter(s.getOutputStream()));
			out.write("100|" + myid + "\r\n");
			out.flush();
			new Thread(this).start();
		} catch (Exception e) {
			System.out.println("접속 실패 에러!!");
			e.printStackTrace();
		}
	}

	public void sendProcess() {
		String msg = chat.globalsend.getText().trim();
		if (msg.length() < 1)
			return;
		try {
			out.write("200|" + msg + "\n");
			out.flush();
		} catch (IOException e) {
			System.out.println("메세지 전송 실패 에러!!");
			e.printStackTrace();
		}
		chat.globalsend.setText("");
		chat.globalsend.requestFocus();
	}

	public void renameProcess() {
		String newName = re.newname.getText().trim();
		try {
			out.write("500|" + newName + "\n");
			re.newname.setText("");
			out.flush();
			re.setVisible(false);
		} catch (IOException e) {
			System.out.println("renameProcess Fail");
			e.printStackTrace();
		}
	}

	public void closeProcess() {
		chat.list.removeAll();
		chat.area.setText("");
		chat.globalsend.setText("");
		chat.whomsend.setText("");
		chat.whom.setText("");
		chat.setVisible(false);
		try {
			out.write("900|\n");
			out.flush();
		} catch (IOException e) {
			System.out.println("종료 실패 에러!!");
			e.printStackTrace();
		}
	}

	public void whomProcess() {
		if (chat.idx == -1) {
			JOptionPane.showMessageDialog(this, "귓속말 상대방을 선택하세요~");
			return;
		}
		if (myid.equals(chat.item)) {
			JOptionPane.showMessageDialog(this, "자기 자신한테는 귓속말이 안되요~");
			return;
		}
		String msg = chat.whomsend.getText();
		try {
			out.write("300|" + chat.item + "|" + msg + "\n");
			out.flush();
			chat.area.append(chat.item + " 에게 귓속말>>" + msg + "\n");
			chat.autoScroll();

			chat.whomsend.setText("");
			chat.whomsend.requestFocus();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void paperProcess() {
		String to = paper.to.getText().trim();
		String temp = paper.letter.getText().trim();
		paper.setVisible(false);
		String message = temp.replace('\n', '\\');
		try {
			out.write("400|" + to + "|" + message + "\n");
			out.flush();
		} catch (Exception e) {
			System.out.println("client paper : " + e);
		}
		paper.to.setText("");
		paper.from.setText("");
		paper.letter.setText("");

	}// paperProcess() end

	public void run() {
		while (true) {
			try {
				String msg = in.readLine();
				System.out.println(msg);
				StringTokenizer st = new StringTokenizer(msg, "|");
				int num = Integer.parseInt(st.nextToken());
				switch (num) {
				case 100:// 로그인
					String nick = st.nextToken();
					String nickall = st.nextToken();
					StringTokenizer token = new StringTokenizer(nickall, "%");
					chat.list.removeAll();
					while (token.hasMoreTokens()) {
						String temp = token.nextToken();
						chat.list.add(temp);
					}
					chat.area.append("▶▶ " + nick + " 님이 입장하였습니다\n");
					chat.autoScroll();
					break;
				case 200:// 전체메세지
					String m = st.nextToken();
					chat.area.append(m + "\n");
					chat.autoScroll();
					break;
				case 300:// 귓속말
					String chkNick = st.nextToken();
					String whispMsg = st.nextToken();
					chat.area.append(chkNick + "[귓속말]>>" + whispMsg + "\n");
					chat.autoScroll();
					break;
				case 400:
					String from=st.nextToken();
					String message=st.nextToken().replace('\\', '\n');
					paper.from.setText(from);
					paper.to.setText(myid);
					paper.letter.setText(message);
					paper.letter.requestFocus();
					paper.setVisible(true);
					paper.card.show(paper.south1,"answer");
					break;
				case 500:// 닉네임변경
					String oldName = st.nextToken();
					String newName = st.nextToken();

					int n = chat.list.getItemCount();
					for (int i = 0; i < n; i++) {
						String temp = chat.list.getItem(i);
						if (oldName.equals(temp)) {
							chat.list.replaceItem(newName, i);
							break;
						}
					}
					if (oldName.equals(myid))
						myid = newName;
					chat.area.append("♡♡ " + oldName + " 님이 " + newName
							+ " 로 닉네임을 변경하였습니다\n");
					break;
				case 800:
					chat.area.append("♧♣ 서버가 종료되었습니다.\n");
					in.close();
					out.close();
					s.close();
					return;
				case 900:// 나가기
					String outNick = st.nextToken();
					if (outNick.equals(myid)) {
						in.close();
						out.close();
						s.close();
						return;
					} else {
						chat.list.remove(outNick);
						chat.area.append("◁◁ " + outNick + " 님이 퇴장하였습니다\n");
						chat.autoScroll();
					}
					break;
				default:
					break;
				}// switch
			} catch (Exception e) {
				System.out.println("client 에러");
				return;
			}
		}// while
	}// run
}
